/**
 * 应用程序基出类
 */
function App() {
    this.appVersion = '1.6.2';
}
/**
 * 获取调用服务器的上下文
 * @return {String}
 */
App.prototype.ctx = function(prefix) {
        var ctx = $api.getStorage("ctx");
        if (!ctx) {
            //ctx = 'http://www.zertone1.com';
            ctx = 'http://lmyhtest.anewbegin.com';
        }
        if (prefix) {
            if (prefix.indexOf('/') != 0) {
                ctx += '/';
            }
            ctx += prefix;
        }
        return ctx;
    }
    /**
     * api载入完成时调用
     * @return {void}
     */
App.prototype.ready = function() {
    api.parseTapmode();
    var statusBarEls = $api.domAll('.fixStatusBar');
    for (var i = 0; i < statusBarEls.length; i++) {
        $api.fixStatusBar(statusBarEls[i]);
    }
    this.addEvt($api.dom('#btn-back'), 'click', function() {
        api.closeWin();
    });
    this.addEvt($api.dom('#btn-back-root'), 'click', function() {
        api.closeToWin({
            name: 'root'
        });
    });
}

/**
 * 对象扩展
 * @param {Object} destination 目标对象
 * @param {Object} source 源对象
 * @return {Object} 扩展对象
 */
App.prototype.extend = function(destination, source) {
    if (source && destination) {
        for (var property in source) {
            destination[property] = source[property];
        }
    }
    return destination;
}

/**
 * 绑定事件
 * @param {DOM[]} els 被绑定事件的DOM元素
 * @param {String} name 事件名称
 * @param {Function} fn 事件函数
 * @param {Boolean} useCapture 是否捕获事件
 * @return {void}
 */
App.prototype.addEvt = function(els, name, fn, useCapture) {
        if (els) {
            if (els.length > 0) {
                for (var i = 0; i < els.length; i++) {
                    var el = els[i];
                    $api.addEvt(el, name, fn, useCapture);
                }
            } else {
                $api.addEvt(els, name, fn, useCapture);
            }
        }
    }
    /**
     * 打开窗口
     * @param {Object} params 窗口参数
     * @return {void}
     */
App.prototype.openWin = function(params) {
        api.openWin(this.extend({
            animation: {
                type: 'movein',
                subType: 'from_right',
                duration: 200
            }
        }, params));
    }
    /**
     * 获取服务器的访问令牌
     * @return {String}
     */
App.prototype.getAccessToken = function() {
        return $api.getStorage("access_token");
    }
    /**
     * 设置服务器的访问令牌
     * @param {String} accessToken
     * @return {void}
     */
App.prototype.setAccessToken = function(accessToken) {
        $api.setStorage("access_token", accessToken);
    }
    /**
     * 清空缓存，保留当前用户信息
     * @return {void}
     */
App.prototype.clearCache = function() {
    var accessToken = this.getAccessToken();
    var user = $api.getStorage("user");
    $api.clearStorage();
    this.setAccessToken(accessToken);
    $api.setStorage("user", user);
}

/**
 * 显示进度视图
 * @param {Object} params 视图参数
 * @return {void}
 */
App.prototype.mask = function(params) {
        api.showProgress(this.extend({
        }, params));
    }
    /**
     * 关闭进度视图
     * @return {void}
     */
App.prototype.unmask = function() {
        api.hideProgress();
    }
    /**
     *
     * 获取元素绝对偏移量
     * @param {DOM} 元素
     * @return {Object} 元素偏移量对象
     */
App.prototype.absOffset = function(el) {
        var top = el.offsetTop;
        var left = el.offsetLeft;
        var width = el.offsetWidth;
        var height = el.offsetHeight;
        var parentEl;
        while (el.offsetParent != null) {
            parentEl = el.offsetParent;
            left = el.offsetLeft;
            top = el.offsetTop;
            el = parentEl;
        }
        return {
            top: top,
            left: left,
            width: width,
            height: height
        }
    }
    /**
     * 字符串格式化，将字符串中“{变量名}”，替换为args中对应的变量值。
     * @param {String} str 被替换的字符串
     * @param {Object} args 替换参数
     * @return {String} 替换后的字符串
     */
App.prototype.format = function(str, args) {
        var result = str;
        if (arguments.length > 1) {
            if (arguments.length == 2 && typeof(args) == "object") {
                for (var key in args) {
                    if (args[key] != undefined) {
                        var reg = new RegExp("({" + key + "})", "g");
                        result = result.replace(reg, args[key]);
                    }
                }
            } else {
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] != undefined) {
                        var reg = new RegExp("({[" + i + "]})", "g");
                        result = result.replace(reg, arguments[i]);
                    }
                }
            }
        }
        result = result.replace(/{\w+}/g, '');
        return result;
    }
    /**
     * 阻止事件冒泡
     * @param {WindowEvent} e 事件
     * @return {void}
     */
App.prototype.stopEvent = function(e) {
        e.stopPropagation();
    }
    /**
     * 阻止默认事件
     * @param {WindowEvent} e 事件
     * @return {void}
     */
App.prototype.stopDefault = function(e) {
    e.preventDefault();
}

/**
 * 获取表单字段元素
 * @param {DOM} el 表单DOM
 * @return {Array} 表单字段元素集合
 */
App.prototype.getFormFields = function(el) {
        var fieldList = [];
        var inputs = el.getElementsByTagName('input');
        for (var i = 0; i < inputs.length; i++) {
            fieldList.push(inputs[i]);
        }
        var textareas = el.getElementsByTagName('textarea');
        for (var i = 0; i < textareas.length; i++) {
            fieldList.push(textareas[i]);
        }
        var selects = el.getElementsByTagName('select');
        for (var i = 0; i < selects.length; i++) {
            fieldList.push(selects[i]);
        }
        return fieldList;
    }
    /**
     * 获取表单内容
     * @param {DOM} el 表单DOM
     * @return {Object} 表单内容对象
     */
App.prototype.getFormValues = function(el) {
        var values = {};

        var fieldList = this.getFormFields(el);

        for (var i = 0; i < fieldList.length; i++) {
            var field = fieldList[i];
            var name = field.getAttribute('name');
            var type = field.getAttribute('type');
            if (name && name != '') {
                var value;
                if (type == 'checkbox') {
                    value = values[name];
                    if (!value) {
                        value = [];
                        values[name] = value;
                    }
                    if (field.checked) {
                        value.push(field.value);
                    }
                } else if (type == 'radio') {
                    if (field.checked) {
                        values[name] = field.value;
                    }
                } else {
                    values[name] = field.value;
                }
            }
        }
        return values;
    }
    /**
     * 获取表单内容
     * @param {DOM} el 表单DOM
     * @param {Object} values 表单内容
     * @return {void}
     */
App.prototype.setFormValues = function(el, values) {
        var fieldList = this.getFormFields(el);
        for (var i = 0; i < fieldList.length; i++) {
            var field = fieldList[i];
            var name = field.getAttribute('name');
            var type = field.getAttribute('type');
            if (name && name != '') {
                var value = values[name];
                if (type == 'checkbox') {
                    if (value) {
                        if (value.length > 0) {
                            var checked = false;
                            for (var j = 0; j < value.length; j++) {
                                if (field.value == value[j]) {
                                    checked = true;
                                    break;
                                }
                            }
                            field.checked = checked;
                        } else {
                            field.checked = false;
                        }
                    } else {
                        field.checked = false;
                    }
                } else if (type == 'radio') {
                    if (value) {
                        field.checked = field.value === value;
                    } else {
                        field.checked = false;
                    }
                } else {
                    field.value = value || '';
                }
            }
        }
    }
    /**
     * 格式化URL
     * @param {String} url URL
     * @param {Object} params URL参数
     * @return {String} 格式化后的URL
     */
App.prototype.formatUrl = function(url, params) {
        var system = $api.getStorage("system");
        url = url.replace('{system}', system || '');
        if (params) {
            for (var key in params) {
                var pnmReg = /\$\(\\?"?\w+\\?"?\)|{\w+}/g;
                var pnvReg = /[\$ \( \) { } \\ "]/g;
                var pnms = url.match(pnmReg);
                for (var i = 0; pnms && i < pnms.length; i++) {
                    var pnm = pnms[i];
                    var pnv = pnm.replace(pnvReg, '');
                    var pv = replaceObj[pnv];
                    if (pv) {
                        url = url.replace(pnm, pv);
                    } else {
                        url = url.replace(pnm, '');
                    }
                }
            }
        }
        console.log('formatUrl：' + url);
        return url;
    }
    /**
     * 格式化URL(远程),若以http://开头则不处理，否则自动增加app.ctx()前缀
     * @param {String} url URL
     * @param {Object} params URL参数
     * @return {String} 格式化后的URL
     */
App.prototype.formatRemoteUrl = function(url, params) {
        if (url.indexOf('http://') != 0) {
            if (url.indexOf('/') == 0) {
                url = this.ctx() + url;
            } else {
                url = this.ctx() + '/' + url;
            }
        }
        return this.formatUrl(url, params);
    }
    /**
     * 远程调用
     * @param {Object} params 调用参数
     * @param {Function} callback 调用完成回调函数
     * @return {void}
     */
App.prototype.ajax = function(params, callback) {
        var headers = {
            deviceId: api.deviceId,
            appVersion: this.appVersion,
            systemType: api.systemType
        };
        var accessToken = this.getAccessToken();
        if (accessToken) {
            headers.access_token = accessToken;
        }
        var options = {
            headers: headers,
            timeout: 20,
            cache: false
        };
        for (var key in params) {
            var value = params[key];
            if (key == 'url') {
                options[key] = this.formatRemoteUrl(value);
            } else {
                options[key] = value;
            }
        }
        if (options.showMask != false) {
            this.mask({});
        }
        var me = this;
        console.log('ajax-req:' + JSON.stringify(options));
        api.ajax(options, function(ret, err) {
            if (options.showMask != false) {
                me.unmask({});
            }

            if (ret) {
                console.log('ajax-rep[success]:' + JSON.stringify(ret));
                if (callback) {
                    callback.call(me, ret, err);
                }
            } else {
                console.log('ajax-rep[error]:' + JSON.stringify(err));
                if (err.body.code == 'NOAUTH') {
                    api.openWin({
                        name: 'my.login_reg',
                        url: 'widget://html/me/login_reg.html'
                    });
                } else {
                    if (callback) {
                        callback.call(me, ret || {}, err);
                    }
                }
            }
        });
    }
    /**
     * 表单提交
     * @param {DOM} el 表单DOM
     * @param {Object} options 提交参数
     * @return {void}
     */
App.prototype.formSubmit = function(el, options) {
    if (!options) {
        options = {};
    }
    var data;
    if (options.data) {
        data = options.data;
    } else {
        var values = this.getFormValues(el);
        data = {
            values: values
        };
    }
    var url = options.url;
    if (!url) {
        url = el.getAttribute('action');
    }
    var method = options.method;
    if (!method) {
        method = el.getAttribute('method') || 'get';
    }
    if (options.showMask != false) {
        this.mask(options.mask);
    }
    this.ajax({
        url: url,
        method: method,
        timeout: 60,
        data: data
    }, function(ret, err) {
        if (options.showMask != false) {
            this.unmask();
        }
        if (ret && ret.errcode == '0') {
            if (options.onSuccess) {
                options.onSuccess.call(this, data, ret);
            } else {
                api.toast({
                    msg: '提交成功！'
                });
            }
        } else {
            if (options.onError) {
                options.onError.call(this, ret, err);
            } else {
                api.alert({
                    title: '提交失败',
                    msg: ret.message || err.message,
                });
            }
        }
    });
};

/**
 * 倒计时
 * @param {Long|Date} date
 * @param {String} fmt
 * @return {String}
 */
App.prototype.dateCountDown = function(date, fmt) {
    date = date || 0;
    fmt = fmt || "dd天hh时mm分ss秒";

    if(!(date instanceof Date)) {
      if (date < 0) {
          date = 0;
      }
      date = new Date(date*1000);
    }

    var day = parseInt(date.getTime() / (24 * 60 * 60 * 1000), 0);
    var hours = date.getHours() - 8;
    if (hours < 0) {
        hours += 24;
    }
    var o = {
        "d+": day, //日
        "h+": hours, //小时
        "m+": date.getMinutes(), //分
        "s+": date.getSeconds(), //秒
        "S": date.getMilliseconds() //毫秒
    };
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            if (k == "d+" && o[k] == 0) {
                fmt = fmt.replace(RegExp.$1, "");
                fmt = fmt.substr(1);
            } else {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
    }

    return fmt;
}

app = new App();
